from django.shortcuts import render,HttpResponse
from .models import Article,Link,Category,Tag,Notice,Valine,About,Site,Social,Skill
from circular.models import Circular
# from activity.models import Activity
import re,mistune

def index(request):
    """首页展示"""
    # status = request.session.get('is_login')
    # if not status:
    #     return redirect('/session_login/')
    if request.method == "GET":
        # 取出所有博客文章
        all_articles = Article.objects.all()
        # 取出要推荐的博客文章
        top_articles = Article.objects.filter(is_recommend=1)
        notices = Notice.objects.all()

        # 取出所有活动
        # activities = Activity.objects.all()

        # 取出置顶的通知
        circulars = Circular.objects.filter(is_settop=1)

        # 需要传递给模板（templates）的对象
        context = {
            'all_articles': all_articles,
            'top_articles': top_articles,
            'notices': notices,
            # 'activities': activities,
            'circulars': circulars,
            }
        # render函数：载入模板，并返回context对象
        return render(request, 'blog/index.html',context)

    
    else:
        # 其实可以在index页面设计一下，取一个div用来展示"---Method Error!---"信息，这样显得样式统一
        # 这样的话下面的HttpResponse()可以替换成render()
        return HttpResponse("---Method Error!---")

# #################################################################################################
# 数学支持参考https://www.cnblogs.com/spaceskynet/p/13347938.html

class MathBlockGrammar(mistune.BlockGrammar):
    block_math = re.compile(r"^\$\$(.*?)\$\$", re.DOTALL)
    latex_environment = re.compile(r"^\\begin\{([a-z]*\*?)\}(.*?)\\end\{\1\}", re.DOTALL)

class MathBlockLexer(mistune.BlockLexer):
    default_rules = ['block_math', 'latex_environment'] + mistune.BlockLexer.default_rules

    def __init__(self, rules=None, **kwargs):
        if rules is None:
            rules = MathBlockGrammar()
        super(MathBlockLexer, self).__init__(rules, **kwargs)

    def parse_block_math(self, m):
        """Parse a $$math$$ block"""
        self.tokens.append({
            'type': 'block_math',
            'text': m.group(1)
        })

    def parse_latex_environment(self, m):
        self.tokens.append({
            'type': 'latex_environment',
            'name': m.group(1),
            'text': m.group(2)
        })

class MathInlineGrammar(mistune.InlineGrammar):
    math = re.compile(r"^\$(.+?)\$", re.DOTALL)
    block_math = re.compile(r"^\$\$(.+?)\$\$", re.DOTALL)
    text = re.compile(r'^[\s\S]+?(?=[\\<!\[_*`~\$]|https?://| {2,}\n|$)')

class MathInlineLexer(mistune.InlineLexer):
    default_rules = ['block_math', 'math'] + mistune.InlineLexer.default_rules

    def __init__(self, renderer, rules=None, **kwargs):
        if rules is None:
            rules = MathInlineGrammar()
        super(MathInlineLexer, self).__init__(renderer, rules, **kwargs)

    def output_math(self, m):
        return self.renderer.inline_math(m.group(1))

    def output_block_math(self, m):
        return self.renderer.block_math(m.group(1))

class MathRendererMixin(mistune.Renderer):
    def block_code(self, code, lang=None):
        code = code.rstrip('\n')
        if not lang:
            lang = 'text'
        code = mistune.escape(code, quote=True, smart_amp=False)
        return '<pre class="language-%s"><code class="language-%s">%s\n</code></pre>\n' % (lang, lang, code)

    def block_math(self, text):
        return '$$%s$$' % text

    def latex_environment(self, name, text):
        return r'\begin{%s}%s\end{%s}' % (name, text, name)

    def inline_math(self, text):
        return '$%s$' % text

class MarkdownWithMath(mistune.Markdown):
    def __init__(self, renderer, **kwargs):
        if 'inline' not in kwargs:
            kwargs['inline'] = MathInlineLexer
        if 'block' not in kwargs:
            kwargs['block'] = MathBlockLexer
        super(MarkdownWithMath, self).__init__(renderer, **kwargs)

    def output_block_math(self):
        return self.renderer.block_math(self.token['text'])

    def output_latex_environment(self):
        return self.renderer.latex_environment(self.token['name'], self.token['text'])

# #################################################################################################

def article_detail(request,id):
    """文章详情页"""
    # 取出相应的文章
    article = Article.objects.get(id=id)
    # 增加阅读数
    article.click_count += 1
    article.save(update_fields=['click_count'])
    valine = Valine.objects.first()#取第一条数据
    #前台mK解析
    mk = MarkdownWithMath(renderer=MathRendererMixin())
    output = mk(r"{}".format(article.content))
    # 需要传递给模板的对象
    context = {
        'valine': valine,
        'article': article,
        'article_detail_html': output,
    }
    # 载入模板，并返回context对象
    return render(request,'blog/article_detail.html',context)

def member(request):
    '''成员详情页'''
    links = Link.objects.all()
    context = {'links':links,}
    return render(request,'blog/member.html',context)

def category_tag(request):
    '''分类和标签页'''
    categories = Category.objects.all()
    tags = Tag.objects.all()
    context = {
        'categories':categories,
        'tags':tags,
    }
    return render(request,'blog/category_tag.html',context)

def article_category(request,id):
    '''文章分类详情页'''
    categories = Category.objects.all()
    articles = Category.objects.get(id=id).article_set.all()#获取该id对应的所有的文章
    context = {
        'categories': categories,
        'id': id,
        'articles': articles
    }
    return render(request, 'blog/article_category.html', context)

def article_tag(request,id):
    '''文章标签详情页'''
    tags = Tag.objects.all()
    articles = Tag.objects.get(id=id).article_set.all()
    context = {
        'tags': tags,
        'id': id,
        'articles': articles
    }
    return render(request, 'blog/article_tag.html', context)

def add_nav(request):
    '''导航栏'''
    category_nav = Category.objects.filter(add_menu=True).order_by('index')
    context = {
        'category_nav': category_nav,
    }
    return render(request, 'layout/header.html', context)

def about(request):
    articles = Article.objects.all().order_by('-add_time')
    categories = Category.objects.all()
    tags = Tag.objects.all()
    about = About.objects.first()
    skill =Skill.objects.all()
    return render(request, 'blog/about.html', {
        'articles': articles,
        'categories': categories,
        'tags': tags,
        'about': about,
        'skill': skill,
    })

def global_params(request):
    """全局变量"""
    #分类是否增加到导航栏
    category_nav = Category.objects.filter(add_menu=True).order_by('index')
    site_name = Site.objects.first().site_name
    logo = Site.objects.first().logo
    keywords = Site.objects.first().keywords
    desc = Site.objects.first().desc
    slogan = Site.objects.first().slogan
    dynamic_slogan = Site.objects.first().dynamic_slogan
    bg_cover = Site.objects.first().bg_cover
    icp_number = Site.objects.first().icp_number
    icp_url = Site.objects.first().icp_url
    social = Social.objects.all()
    return {
        'category_nav': category_nav,
        'SITE_NAME': site_name,
        'LOGO': logo,
        'KEYWORDS': keywords,
        'DESC': desc,
        'SLOGAN': slogan,
        'DYNAMIC_SLOGAN': dynamic_slogan,
        'BG_COVER': bg_cover,
        'ICP_NUMBER': icp_number,
        'ICP_URL': icp_url,
        'social': social,
    }